using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace XnaDevRu.Bullet
{
	// DefaultMotionState provides a common implementation to synchronize world transforms with offsets
	public class DefaultMotionState : MotionState
	{
		private Matrix _graphicsWorldTransform;
		private Matrix _centerOfMassOffset;
		private Matrix _startWorldTransform;
		private object _userData;

		public DefaultMotionState()
			: this(Matrix.Identity, Matrix.Identity) { }

		public DefaultMotionState(Matrix startTransform, Matrix centerOfMassOffset)
		{
			_graphicsWorldTransform = startTransform;
			_centerOfMassOffset = centerOfMassOffset;
			_startWorldTransform = startTransform;
		}

		public Matrix GraphicsWorldTransform { get { return _graphicsWorldTransform; } set { _graphicsWorldTransform = value; } }
		public Matrix CenterOfMassOffset { get { return _centerOfMassOffset; } set { _centerOfMassOffset = value; } }
		public Matrix StartWorldTransform { get { return _startWorldTransform; } set { _startWorldTransform = value; } }
		public object UserData { get { return _userData; } set { _userData = value; } }

		// synchronizes world transform from user to physics
		public override void GetWorldTransform(out Matrix centerOfMassWorldTrans)
		{
            centerOfMassWorldTrans = MathHelper.InvertMatrix(_centerOfMassOffset) * _graphicsWorldTransform;
		}

		// synchronizes world transform from physics to user
		// Bullet only calls the update of worldtransform for active objects
		public override void SetWorldTransform(Matrix centerOfMassWorldTrans)
		{
			_graphicsWorldTransform = MatrixOperations.Multiply(centerOfMassWorldTrans, _centerOfMassOffset);
			_graphicsWorldTransform.Translation = centerOfMassWorldTrans.Translation;
		}

		// Bullet gives a callback for objects that are about to be deactivated (put asleep)
		// You can intercept this callback for your own bookkeeping. 
		// Also you can return false to disable deactivation for this object this frame.
		public override bool DeactivationCallback(object userData)
		{
			return true;
		}
	}
}
